package com.qijian.common.notice;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSON;
import com.qijian.common.core.redis.RedisCache;
import com.qijian.common.utils.EmailUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Data
@Component
@NoArgsConstructor
public class EmailNotice {


    public static String host;

    private String to;
    private String title;
    private String content;

    private String url;
    private UrlParams params;
    List<Object> p;

    @Value("${external.host}")
    public void setHost(String host) {
        EmailNotice.host = host;
    }

    private final static String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAK+uaI2hW0H8bfuOtnIpeQK6T5W0oFd42mg7XW28fAyBetiTubdxe9DLRDPcAIrEmaHzgjwyI5WJqN6rfm4s1Wdlh30UScJPCq7GDGyupJc19WRFOF2OZ8kjjyB92j6TGSB6F/cwphVqxFNlikiNLeqrGoPmKBGYBTjuHo/Ez+aLAgMBAAECgYA2WfN/yclVb1bJalwYkqsdBG4Fx1WJ6lpLv/4GKreIGPDcG0vsLIBdVt2ZW7mRNQTA3XjPzcVDiMzFYvIg/N7idIWIObcx/RPZUjDWskrsNZo2gMCwgZiPupyG6iI2i9CehkjwcFU1Ydd+VFUKCWO4vTCM6nMVySUbawxyiOHVpQJBANXKH3hxTsWyF0Yv+p1qyM1uBmw9258UfPy0LW5+QpHJxFifbNspqbG8VV29nLFG8X9gIn3D9HEnxAi+VnU/Eu8CQQDSXh/BvmHYC+PBD2ZHeOR3O5o9ECH8V43+nNxC939cMlwc7qeMF4klr718+JyZ7X/Xdtrbpe/b8xjP41NfiHYlAkB8ts9K/JZeP3jSSfTh1cRUCoYWqLMwhswuwpDqLx94WoJ+zGm9I/3JIDuQVqdMxzzj+FnGkgRL6k2yaA6ZkPTjAkAlBEL6SJHW/mCZPCh3MyKgiHBfhlM0oANwZhGsBvj2NDZZMPVyhUGwy/e/4c9MlqoEM/nW5KAMR/55tjqZeN2xAkAN+69sBaXKxmWtRhgMUSjfzbc8qx055aZqaVlICK6ajXthZluMHgHgQOtfESNZtJtRudaJadrOHB/Lnryvxmng";
    private final static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvrmiNoVtB/G37jrZyKXkCuk+VtKBXeNpoO11tvHwMgXrYk7m3cXvQy0Qz3ACKxJmh84I8MiOViajeq35uLNVnZYd9FEnCTwquxgxsrqSXNfVkRThdjmfJI48gfdo+kxkgehf3MKYVasRTZYpIjS3qqxqD5igRmAU47h6PxM/miwIDAQAB";

    public static final RSA rsa = new RSA(privateKey, publicKey);

    private static String eMailHtml = "<html>\n" +
            "\n" +
            "<head>\n" +
            "</head>\n" +
            "\n" +
            "<body >\n" +
            "    <img src=\"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.2008php.com%2F09_Website_appreciate%2F10-07-11%2F1278861720_g.jpg&refer=http%3A%2F%2Fwww.2008php.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1665287097&t=b0c1a3f275aca85a10de6f3dce9a160d\">\n" +
            "</body>\n" +
            "</html>";

    public EmailNotice(String to, String title, String content, String url, Long id, Date deadline, List<Object> p) {
        this.to = to;
        this.title = title;
        this.content = content;
        this.url = url;
        if (id != null) {
            this.params = new UrlParams(id, deadline == null ? null : LocalDateTimeUtil.of(deadline));
        }
        this.p = p;
    }

    public void encryptParams() {
        if (this.params != null) {
            this.url = host + this.url + "?uuid=" + this.params.uuid + "&p=" + URLUtil.encodeQuery(rsa.encryptBase64(JSON.toJSONString(this.params), KeyType.PublicKey));
            this.p.add(this.url);
        }else{
            this.p.add("javaScript:;\" class=\"displayNone");
        }
    }

    public static UrlParams parseParams(String param) {
        UrlParams params;
        try {
            String data = EmailNotice.rsa.decryptStr(param, KeyType.PrivateKey);
            params = JSON.parseObject(data, UrlParams.class);
        } catch (Exception ex) {
            throw new IllegalArgumentException("参数解析异常！");
        }
        params.canOperation();
        return params;
    }

    public static void sendEmail(String key, List<EmailNotice> notices, File... filePaths) {
        if (notices.size() > 0) {
            notices.forEach(n -> {
                n.encryptParams();
                EmailUtil.sendEmail(key, Collections.singletonList(n.getTo()), n.getTitle(), n.getP(), filePaths);
//                EmailUtil.send(EmailUtil.ACCOUNT, n.getTo(), n.getTitle(), fullContent, true);
            });
        }
    }

    @Data
    @Component
    @NoArgsConstructor
    public static class UrlParams {
        private Long timestamp;
        //默认拒绝才是安全的，默认没有'有效期'
        private Long validity = 0L;

        private Long id;

        private LocalDateTime deadLine;

        private String uuid;

        private static RedisCache redisCache;

        @Autowired
        public void setRedisCache(RedisCache redisCache) {
            UrlParams.redisCache = redisCache;
        }

        public void canOperation() {
            LocalDateTime of = LocalDateTimeUtil.of(this.timestamp);
            LocalDateTime now = LocalDateTime.now();
            if (now.isAfter(of.plus(this.validity, ChronoUnit.MILLIS)))
                throw new IllegalStateException("已超过链接有效期，请联系业务获取新的链接！");
            else if (now.isAfter(deadLine))
                throw new IllegalStateException("已超过截止日期，无法操作，可以联系业务员获取新的链接！");
        }

        public UrlParams(Long id, LocalDateTime deadLine) {
            LocalDateTime now = LocalDateTime.now();
            if (deadLine == null)
                deadLine = now.plusDays(3);
            this.timestamp = LocalDateTimeUtil.toEpochMilli(now);
            Duration duration = Duration.between(now, deadLine);
            this.validity = duration.toMillis();
            this.id = id;
            this.deadLine = deadLine;
            this.uuid = UUID.randomUUID().toString();
            redisCache.setCacheObject(uuid, uuid, validity, TimeUnit.MILLISECONDS);
        }
    }

}
